﻿using System;
using RayDen.RayEngine.Core;
using RayDen.RayEngine.Core.Devices;
using RayDen.RayEngine.Core.Interface;
using RayDen.RayEngine.Core.Threads;
using RayDen.RayEngine.Managers;
using RayDen.RayEngine.Samplers;

namespace RayDen.RayEngine.Engines.PathTracer.Production
{
    [RenderingEngine(EngineType = RenderingEngines.BiasedPathTracer)]
    public class ProductionPathTracerEngine : BaseRenderingEngine
    {
        public ProductionPathTracerEngine(RayEngineScene scene) : base(scene)
        {
            if (!GlobalConfiguration.Instance.AdaptiveFilm)
            {
                throw new ApplicationException("Adaptive film should be used");
            }
        }

        public override RenderThread CreateRenderThread(int threadIndex, IntersectionEngine intersectionDevice, RayEngineScene scene,
            IImageFilm film, IFrameManager manager, SamplingContext samplingContext)
        {
            return new DeviceRenderThread<PathBuffer<ProductionPathTracerPathSampler>>(threadIndex, intersectionDevice, scene,
                                                                   LowLatencySampling, film, samplingContext, manager);
        }

        public override ISampler CreateSampler(int width, int height, int maxPathDepth, int threadIndex, int screenStartLine, int windowHeight)
        {
            return new AdaptiveProgressiveSampler
            {
                screenWidth = width,
                screenHeight = height,
                lowLatency = true,
                screenStartLine = screenStartLine + 1,
                tIdx = threadIndex,
                Film = FilmFactory.Cache as AdaptiveImageFilm
            };
        }

        public override IImageFilm CreateFilm(int width, int height)
        {
            return FilmFactory.Cache;
        }
    }
}